; ______ _ _ _ __ __ _
; | ____| | (_) | \ \ / / | |
; | |__ __| |_| |_ ___ _ __ \ \ /\ / /___ _ __ __| |___
; | __| / _` | | __|/ _ \| '__| \ \/ \/ // _ \| '__/ _` / __|
; | |____| (_| | | |_| (_) | | \ /\ /| (_) | | | (_| \__ \
; |______|\__,_|_|\__|\___/|_| \/ \/ \___/|_| \__,_|___/
; block editor
keyCC equ -125 ; key code for ctrl c (copy line)
keyCV equ -106 ; key code for ctrl v (paste line)
keyCI equ -119 ; key code for ctrl i (insert line)
keyCD equ -124 ; key code for ctrl d (delete line)
keyCO equ -113 ; key code for ctrl o (previous block)
keyCP equ -112 ; key code for ctrl p (next block)
keyF9 equ 15 ; key code for function 9 (back)
keyF7 equ 1 ; key code for function 7 (tab)
keyF4 equ 2 ; key code for function 4 (escape)
keyF3 equ 7 ; key code for function 3 (erase line)
keyF2 equ 4 ; key code for function 2 (insert/overwrite)
keyF1 equ 3 ; key code for function 1 (del)
keyFE equ 11 ; cursor up keycode
keyFS equ 8 ; cursor left keycode
keyFD equ 9 ; cursor right keycode
keyFX equ 10 ; cursor down keycode
keyFeq equ 5 ; keycode for function = (quit)
keyRET equ 13 ; keycode for ENTER key
savkey equ scrx ; borrow scrX memory location for saving
; keypresses
_edit clr @csrflg ; clear shared cursor flash flag
; (shared with forcnt)
clr @temp2 ; next block to load
mov *stack,r0 ; get address from BLOCK
mov r0,r7 ; copy it
jne _edit1 ; if not zero then continue
inct stack ; else BLOCK failed to load block.
b @retB0 ; Remove vdp address from stack and exit
; determine if block is dirty or clean:
; display * next to block number if dirty otherwise display a space
_edit1 jgt _edit4 ; jump if dirty bit not set
li r6,_edit4 ; load return address
bl @disupd ; write CHANGED to screen
_edit4 andi r7,>7fff ; remove dirty bit if set
mov r7,*stack ; write it back, we'll use it further on...
bl @csrdef ; define cursor udg
clr @epage ; set page to first page
clr @temp ; initialise insert/overwrite mode
bl @draws ; draw static parts of the display
bl @drawd ; draw dynamic parts of the display
bl @insovr ; display mode
clr @csrx ; used for cursor x
clr @csry ; used for cursor y
clr @cursrd ; reset cursor delay
bl @delay ; small delay to give the user time to
data 30000 ; release the enter key!
; editor main loop
; keyboard scanning and auto-repeat
edml2 bl @scnkey ; get key in r7
edml4 mov r7,@savkey ; save the keypress
ci r7,>ffff ; nothing pressed?
jeq docfl ; if nothing pressed then do cursor flash
li r13,edml3 ; set something pressed - set return point
; for post keypress processing
jmp chkent ; process the key press
edml3 mov @kdel,r0 ; get keyboard repeat delay from kdel
srl r0,8 ; upper byte to lower byte
sla r0,1 ; move right one. multiplied by 2
edml5 bl @scnkey ; scan again
c r7,@savkey ; same key as last time?
jeq edml6 ; if yes then decrement delay
jmp edml4 ; different key - go process it
edml6 dec r0 ; decrement counter
jne edml5 ; check again
li r13,edml7 ; counter expired. set return point
jmp chkent ; go process key
edml7 movb @kdel+1,r0 ; get short delay from kdel low-byte
srl r0,8 ; to low byte
jmp edml5 ; repeat
; do cursorflash
docfl li r0,>0100
a r0,@cursrd
jne edml2 ; time to flash cursor? loop if not
inv @csrflg ; invert the cursor flag
jeq oncsr ; if 0 do cursor on
bl @csroff ; else do cursor off
jmp edml2
oncsr bl @csron
jmp edml2
; check for enter key
chkent ci r7,keyRET ; return/enter pressed?
jne keycor ; skip if not
clr @csrx ; move to left most column
clr @epage ; move to left page
inc @csry ; move down a line
mov @csry,r0 ; check y
ci r0,16 ; 16?
jne keyen1 ; skip if not
clr @csry ; clip to 15
keyen1 bl @drawd ; render display
b *r13 ; continue
; check control keys
; ; check CTRL O (previous block)
keycor ci r7,keyCO
jne keycpr
mov @lstblk,@temp2
dec @temp2 ; decrement block number to load
rt4th inct stack ; remove BLOCK address from stack
li r12,_next ; restore pointer to NEXT
b @retB0 ; return to forth
; ; check CTRL P (next block)
keycpr ci r7,keyCP
jne keycdr
mov @lstblk,@temp2
inc @temp2 ; increment block number to load
jmp rt4th ; return to forth
; ; check CTRL D (delete line)
keycdr ci r7,keyCD ; ctrl d pressed?
jne keycir ; skip if not
bl @needud ; set this blocks' status to dirty
; calculate end address of buffer
mov *stack,r6 ; vdp buffer address
ai r6,1023 ; point to last byte of buffer
; calculate start point
mov @csry,r0 ; get current line
inc r0 ; move down a line
sla r0,6 ; multiply by buffer line length
a *stack,r0 ; add vdp buffer start address
keycd1 li r2,64 ; read a line...
mov @here,r1 ; ...into scroll buffer
bl @_vmbr ; read the line
ai r0,-64 ; move up one line
mov @here,r1 ; source
li r2,64 ; count
bl @_vmbw0 ; write the line
ai r0,128 ; move down 2 lines
c r0,r6 ; done all?
jlt keycd1 ; loop if not
; blank the last line... r6 points to last byte, so...
mov r6,r0 ; place in r0 for VDP
ai r0,-63 ; move to start of last line in buffer
li r1,>2000 ; space character
li r2,64 ; line length
bl @vsbwmi ; write spaces
bl @rsrc ; render source
b *r13 ; continue
; ; check CTRL I (insert line)
keycir ci r7,keyCI ; ctrl i pressed?
jne keyccr ; skip if not
bl @needud ; set this blocks' status to dirty
; get current line address
mov @csry,r6 ; current y
ci r6,15 ; on the last line?
jeq keyci2 ; if so, just erase last line
sla r6,6 ; multiply by line length
a *stack,r6 ; add vdp buffer address
; find last line of buffer
mov *stack,r0 ; buffer start address
ai r0,14*64 ; move to last line but 1 (15th line)
keyci1 mov @here,r1 ; buffer address
li r2,64 ; count
bl @_vmbr ; read into buffer
ai r0,64 ; move down a line
mov @here,r1